package com.gitee.simons.common.tree;

import com.gitee.simons.common.utils.GsonUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * 树形构建工具
 * @author JSM
 */
public class TreeBuilder {

	public <T extends TreeModel> List<Node<T>> buildListToTree(List<Node<T>> dirs) {
		List<Node<T>> roots = findRoots(dirs);
		for (Node<T> root : roots) {
			findChildren(root, dirs);
		}
		return roots;
	}

	public <T extends TreeModel> List<Node<T>> findRoots(List<Node<T>> allNodes) {
		List<Node<T>> results = new ArrayList<Node<T>>();
		for (Node<T> node : allNodes) {
			boolean isRoot = true;
			for (Node<T> comparedOne : allNodes) {
				if (node!= null && comparedOne!=null&& node.getEntity().getParentId().equals( comparedOne.getEntity().getId() )) {
					isRoot = false;
					break;
				}
			}
			if (isRoot) {
				results.add(node);
			}
		}
		return results;
	}

	public <T extends TreeModel> List<Node<T>> findChildren(Node<T> root, List<Node<T>> allNodes) {
		List<Node<T>> children = new ArrayList<Node<T>>();

		for (Node<T> comparedOne : allNodes) {
			if (comparedOne.getEntity().getParentId().equals( root.getEntity().getId())) {
				children.add(comparedOne);
			}
		}
		for (Node<T> child : children) {
			List<Node<T>> tmpChildren = findChildren(child, allNodes);
			child.setChildren(tmpChildren);
		}
		root.setChildren(children);
		return children;
	}

	public <T extends TreeModel> List<Map<String,Object>> node2Tree(List<Node<T>> allNodes){
		List<Map<String,Object>> result = new ArrayList<Map<String, Object>>();

		for (Node<T> node : allNodes) {
			Map<String,Object> item = this.object2Map(node);
			if(node.getChildren() != null){
				String curParent = null;
				item.put("children", this.node2Tree(node.getChildren()));
			}
			result.add(item);
		}

		return result;
	}

	public <T extends TreeModel> Map<String,Object> object2Map(Node<T> node){
		Map<String,Object> result = GsonUtil.gson.fromJson(GsonUtil.gson.toJson(node.getEntity()), Map.class);
		result.put("label", result.get("name"));
		result.put("key", result.get("id"));
		return result;
	}

	private static final TreeBuilder TD = new TreeBuilder();

	public static <T extends TreeModel> List<Map<String,Object>> model2Tree(Collection<T> modelList){
		List<Node<T>> nodelList = new ArrayList<Node<T>>();

		for(T item : modelList){
			Node<T> node = new Node<T>();
			node.setEntity(item);
			nodelList.add(node);
		}
		List<Node<T>> roots = TD.buildListToTree(nodelList);
		return TD.node2Tree(roots);
	}

}